/**
 * @Author:  renyc
 * @Date: 2022年12月16日13:59:14
 */

import * as Cesium from "cesium/Cesium";

/**
 * @class Skyline
 * 
 * @description 天际线效果
 * 
 * 2022-12-16
 *    初步实现天际线效果，但还存在问题：模型边缘被检测出来，在cesium_ucas的skyline.html中没有这一问题
 * 
 */
class Skyline{

    /**
     * 
     * @param {Viewer} _viewer 
     * @param {Object} options 
     */
    constructor(_viewer, options){
        this._viewer = _viewer;
        this._options = options;

        this._postStages = undefined;
        this._silhouette = undefined;
    }

    /**
     * 启用效果
     */
    enable(){
        if(this._postStages){
            this._silhouette.enabled=true;
            return;
        }
        this._postStages = this._viewer.scene.postProcessStages;

        /**
         * 第1步：绘制轮廓线作为中间参数
         */
        let edgeDetection = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();

        /**
         * 第2步：绘制深度纹小于1，的为红色区域
         */
        let postProccessStage = new Cesium.PostProcessStage({
            //此后处理阶段的唯一名称，供组合中其他阶段参考，如果未提供名称，将自动生成GUID
            // name:name,
            //unform着色器对象 textureScale
            fragmentShader: 'uniform sampler2D colorTexture;' +
                'uniform sampler2D depthTexture;' +
                'varying vec2 v_textureCoordinates;' +
                'void main(void)' +
                '{' +
                ' float depth = czm_readDepth(depthTexture, v_textureCoordinates);' +
                ' vec4 color = texture2D(colorTexture, v_textureCoordinates);' +
                ' if(depth<1.0 - 0.000001){' +
                '   gl_FragColor = color;' +
                ' }' +
                ' else{' +            
                '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
                ' }' +
                '}'
        });
    
        /**
         * 第3步：
         * 1）如果有深度，则按照原本的原色绘制，如果没有深度
         * 2）如果没有深度，有轮廓就绘制轮廓，否则就按原本的颜色绘制。
         */
        //PostProcessStage:要使用的片段着色器。默认sampler2D制服是colorTexture和depthTexture。
        let postProccesStage_1 = new Cesium.PostProcessStage({
            // name:obj.name+'_1',
            fragmentShader: 'uniform sampler2D colorTexture;' +
                'uniform sampler2D redTexture;' +
                'uniform sampler2D silhouetteTexture;' +
                'varying vec2 v_textureCoordinates;' +
                'void main(void)' +
                '{' +
                ' vec4 redcolor=texture2D(redTexture, v_textureCoordinates);' +
                ' vec4 silhouetteColor = texture2D(silhouetteTexture, v_textureCoordinates);' +
                ' vec4 color = texture2D(colorTexture, v_textureCoordinates);' +
                ' if(redcolor.r == 1.0){' +
                '   gl_FragColor = mix(color, vec4(5.0,0.0,0.0,1.0), silhouetteColor.a);' +
                ' }' +
                ' else{' +
                '   gl_FragColor = color;' +
                ' }' +
                '}',
            //uniform着色器对象
            uniforms: {
                redTexture: postProccessStage.name,
                silhouetteTexture: edgeDetection.name
            }
        });
    
        //如果inputPreviousStageTexture 是 true，则每个阶段输入是场景渲染到的输出纹理或之前执行阶段的输出纹理
        //如果inputPreviousStageTexture是false，则合成中每个阶段的输入纹理都是相同的
        this._silhouette= new Cesium.PostProcessStageComposite({
            //PostProcessStage要按顺序执行 的 s 或组合的数组。
            stages:[edgeDetection,postProccessStage,postProccesStage_1],
            //是否执行每个后处理阶段，其中一个阶段的输入是前一个阶段的输出。否则每个包含阶段的输入是组合之前执行的阶段的输出
            inputPreviousStageTexture:false,
            //后处理阶段制服的别名
            uniforms:edgeDetection.uniforms
        })
        this._postStages.add(this._silhouette);
    }
    

    /**
     * 关闭效果
     */
    disable(){
        if(this._silhouette.enabled){
            this._silhouette.enabled=false;
        }
    }

}

export default Skyline;